/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package es.cv.gui;

import es.cv.core.CoreModule;

import java.awt.Toolkit;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.StringTokenizer;

import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.RotatedRect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

import javax.swing.JCheckBox;

public class MainWindow extends javax.swing.JFrame {

	// DECLARACION DE VARIABLES GLOBALES
	String fileNoData = "src" + File.separator + "es" + File.separator + "img" + File.separator + "nodata.jpg";
	String fileLogo = "src" + File.separator + "es" + File.separator + "icon" + File.separator + "opencv-logo.png";
	String workingDirectory = System.getProperty("user.dir");

	private String rutaNoData = workingDirectory + File.separator + fileNoData;
	private String rutaLogo = workingDirectory + File.separator + fileLogo;

	private javax.swing.JPanel jPanel1;
	private javax.swing.JPanel jPanel2;
	private javax.swing.JPanel jPanelOriginal;
	private javax.swing.JPanel jPanelMod;

	private javax.swing.JLabel jLabelOriginal;
	private javax.swing.JLabel jLabelEstado;
	private javax.swing.JLabel jLabelMod;

	private javax.swing.JMenuBar jMenuBar;

	private javax.swing.JMenu jMenuArchivo;
	private javax.swing.JMenuItem jMenuItemAbrirImagen;
	private javax.swing.JMenuItem jMenuItemGuardarImagen;
	private javax.swing.JMenuItem jMenuItemUsarMod;
	private javax.swing.JMenuItem jMenuItemSalir;

	private javax.swing.JMenu jMenuEdicion;
	private javax.swing.JMenuItem jMenuItemLimpiar;
	private javax.swing.JMenuItem jMenuItemAjustar;

	private javax.swing.JMenu jMenuHerramientas;
	private javax.swing.JMenuItem jMenuItemAGris;
	private javax.swing.JMenuItem jMenuItemAHSV;
	private javax.swing.JMenuItem jMenuItemEqualizer;
	private javax.swing.JMenuItem jMenuItemBackProjection;
	private javax.swing.JMenuItem jMenuItemEroding;
	private javax.swing.JMenuItem jMenuItemDilating;
	private javax.swing.JMenuItem jMenuItemOpen;
	private javax.swing.JMenuItem jMenuItemClose;
	private javax.swing.JMenuItem jMenuItemHu;
	private javax.swing.JMenuItem jMenuItemCany;
	private javax.swing.JMenuItem jMenuItemHoughThreshold;
	private javax.swing.JMenuItem jMenuItemThreshold;
	private javax.swing.JMenuItem jMenuItemWaterShed;
	private JMenuItem jMenuItemFindContours;
	private JMenuItem jMenuItemSift;
	private JMenuItem jMenuItemSurf;
	private JMenuItem jMenuItemSaveDescriptors;
	private JMenuItem jMenuItemCascade;
	private JMenuItem jMenuItemBackgroundSubtraction;
	private JMenuItem jCentroide;

	private javax.swing.JMenu jMenuFiltros;
	private javax.swing.JMenuItem jMenuItemGaussian;

	private javax.swing.JMenu jMenuConvolucion;
	private javax.swing.JMenuItem jMenuItemNucleo;
	private javax.swing.JMenuItem jMenuItemBordes;

	private javax.swing.JMenu jMenuAyuda;
	private JMenuItem jMenuItemLotes;

	Mat bydefault;
	Mat resizeImageByDefault;
	Mat image;
	Mat resizeImage;
	Mat imageMod;
	Mat resizeImageMod;
	Size size;
	private JSeparator separator;
	private JMenuItem mntmOpenSecondImage;
	private JMenuItem jMenuItemSIFTDrawMatches;
	String filename;
	private JMenuItem jFinalTracking;

	static {
		System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
	}

	/**
	 * Main
	 * 
	 * @param args
	 */
	public static void main(String args[]) {
		try {
			for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
				if ("Nimbus".equals(info.getName())) {
					UIManager.setLookAndFeel(info.getClassName());
					break;
				}
			}
		} catch (Exception e) {

		}

		java.awt.EventQueue.invokeLater(new Runnable() {
			public void run() {
				new MainWindow().setVisible(true);
			}
		});
	}

	public MainWindow() {
		initComponents();
		initModel();
	}

	private void initModel() {
		setIconImage(Toolkit.getDefaultToolkit().getImage(rutaLogo));
		size = new Size(jPanelOriginal.getWidth(), jPanelOriginal.getHeight());
		resetData();
	}

	@SuppressWarnings("unchecked")
	private void initComponents() {
		jPanel2 = new javax.swing.JPanel();
		jPanelOriginal = new javax.swing.JPanel();
		jLabelOriginal = new javax.swing.JLabel();
		jPanelMod = new javax.swing.JPanel();
		jLabelMod = new javax.swing.JLabel();
		jPanel1 = new javax.swing.JPanel();
		jLabelEstado = new javax.swing.JLabel();

		jMenuBar = new javax.swing.JMenuBar();
		jMenuArchivo = new javax.swing.JMenu();
		jMenuItemAbrirImagen = new javax.swing.JMenuItem();
		jMenuItemGuardarImagen = new javax.swing.JMenuItem();
		jMenuItemUsarMod = new JMenuItem();
		jMenuItemSalir = new javax.swing.JMenuItem();

		jMenuEdicion = new javax.swing.JMenu();
		jMenuItemLimpiar = new javax.swing.JMenuItem();
		jMenuItemAjustar = new javax.swing.JMenuItem();

		jMenuHerramientas = new javax.swing.JMenu();
		jMenuItemAGris = new javax.swing.JMenuItem();
		jMenuItemAHSV = new javax.swing.JMenuItem();
		jMenuItemEqualizer = new JMenuItem();
		jMenuItemBackProjection = new JMenuItem();
		jMenuItemEroding = new JMenuItem();
		jMenuItemDilating = new JMenuItem();
		jMenuItemOpen = new JMenuItem();
		jMenuItemClose = new JMenuItem();
		jMenuItemBordes = new JMenuItem();
		jMenuItemCany = new JMenuItem();
		jMenuItemHu = new JMenuItem();		
		jMenuItemSaveDescriptors = new JMenuItem();
		jMenuItemCascade = new JMenuItem();
		jMenuItemBackgroundSubtraction = new JMenuItem();
		jCentroide = new JMenuItem();

		jMenuItemHu.setEnabled(false);
		
		jMenuFiltros = new JMenu();
		jMenuItemGaussian = new JMenuItem();

		jMenuConvolucion = new JMenu();
		jMenuItemNucleo = new JMenuItem();

		jMenuItemHoughThreshold = new JMenuItem();

		jMenuAyuda = new javax.swing.JMenu();
		jMenuItemLotes = new JMenuItem();

		setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
		setTitle("Magic Lab (Computer Vision)");
		setFocusCycleRoot(false);
		setPreferredSize(new java.awt.Dimension(728, 550));
		setResizable(true);

		jPanel2.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
		jPanel2.setLayout(new javax.swing.BoxLayout(jPanel2, javax.swing.BoxLayout.X_AXIS));

		jPanelOriginal.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
		jPanelOriginal.setLayout(new java.awt.BorderLayout());
		jPanelOriginal.add(jLabelOriginal, java.awt.BorderLayout.CENTER);

		jPanel2.add(jPanelOriginal);

		jPanelMod.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
		jPanelMod.setLayout(new java.awt.BorderLayout());
		jPanelMod.add(jLabelMod, java.awt.BorderLayout.CENTER);

		jPanel2.add(jPanelMod);

		getContentPane().add(jPanel2, java.awt.BorderLayout.CENTER);

		jPanel1.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.LOWERED));
		jPanel1.setLayout(new javax.swing.BoxLayout(jPanel1, javax.swing.BoxLayout.LINE_AXIS));

		jLabelEstado.setText("-");
		jPanel1.add(jLabelEstado);

		getContentPane().add(jPanel1, java.awt.BorderLayout.PAGE_END);

		jMenuArchivo.setText("File");

		jMenuItemAbrirImagen.setText("Open...");
		jMenuItemAbrirImagen.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jMenuItemAbrirImagenActionPerformed(evt);
			}
		});
		jMenuArchivo.add(jMenuItemAbrirImagen);

		jMenuItemGuardarImagen.setText("Save as...");
		jMenuItemGuardarImagen.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jMenuItemGuardarImagenActionPerformed(evt);
			}
		});
		
		mntmOpenSecondImage = new JMenuItem("Open a second image...");
		mntmOpenSecondImage.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				jMenuItemAbrirSegundaImagenActionPerformed(evt);
			}
		});
		jMenuArchivo.add(mntmOpenSecondImage);
		jMenuArchivo.add(jMenuItemGuardarImagen);

		jMenuArchivo.add(new JSeparator());

		jMenuItemUsarMod.setText("Use modified as source");
		jMenuItemUsarMod.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jMenuItemUsarModActionPerformed(evt);
			}
		});
		jMenuArchivo.add(jMenuItemUsarMod);

		jMenuArchivo.add(new JSeparator());

		jMenuItemSalir.setText("Exit");
		jMenuItemSalir.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jMenuItemSalirActionPerformed(evt);
			}
		});
		jMenuArchivo.add(jMenuItemSalir);

		jMenuBar.add(jMenuArchivo);

		jMenuEdicion.setText("Edit");

		jMenuItemLimpiar.setText("Clear");
		jMenuItemLimpiar.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jMenuItemLimpiarActionPerformed(evt);
			}
		});
		jMenuEdicion.add(jMenuItemLimpiar);

		jMenuItemAjustar.setText("Resize");
		jMenuItemAjustar.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jMenuItemAjustarActionPerformed(evt);
			}
		});
		jMenuEdicion.add(jMenuItemAjustar);

		jMenuBar.add(jMenuEdicion);

		jMenuHerramientas.setText("Tools");

		jMenuItemAGris.setText("To gray");
		jMenuItemAGris.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jMenuItemAGrisActionPerformed(evt);
			}
		});
		jMenuHerramientas.add(jMenuItemAGris);

		jMenuItemAHSV.setText("To HSV");
		jMenuItemAHSV.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jMenuItemAHSVActionPerformed(evt);
			}
		});
		jMenuHerramientas.add(jMenuItemAHSV);

		jMenuHerramientas.add(new JSeparator());

		jMenuItemEqualizer.setText("Equalize");
		jMenuItemEqualizer.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jMenuItemEqualizerActionPerformed(evt);
			}
		});
		jMenuHerramientas.add(jMenuItemEqualizer);

		jMenuItemBackProjection.setText("Back Projection");
		jMenuItemBackProjection.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jMenuItemBackProjectionActionPerformed(evt);
			}
		});
		jMenuHerramientas.add(jMenuItemBackProjection);

		separator = new JSeparator();
		jMenuHerramientas.add(separator);

		jMenuItemThreshold = new JMenuItem("Threshold");
		jMenuItemThreshold.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jMenuItemThresholdActionPerformed(evt);
			}
		});
		jMenuHerramientas.add(jMenuItemThreshold);

		jMenuItemWaterShed = new JMenuItem("Watershed");
		jMenuItemWaterShed.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jMenuItemWhatershedActionPerformed(evt);
			}
		});
		jMenuHerramientas.add(jMenuItemWaterShed);
		
		jMenuItemFindContours = new JMenuItem("Find Contours");
		jMenuItemFindContours.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				jMenuItemFindContoursActionPerformed(evt);
			}
		});
		jMenuItemFindContours.setEnabled(false);
		jMenuHerramientas.add(jMenuItemFindContours);
		
		jMenuItemSift = new JMenuItem("SIFT");
		jMenuItemSift.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				jMenuItemSiftActionPerformed(evt);
			}
		});
		jMenuItemSift.setEnabled(false);
		jMenuHerramientas.add(jMenuItemSift);

		jMenuItemSurf = new JMenuItem("SURF");
		jMenuItemSurf.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				jMenuItemSurfActionPerformed(evt);
			}
		});
		
		jMenuItemSIFTDrawMatches = new JMenuItem("SIFT Draw Matches");
		jMenuItemSIFTDrawMatches.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				jMenuItemSIFTDrawMatchestActionPerformed(evt);
			}
		});
		jMenuItemSIFTDrawMatches.setEnabled(false);
		jMenuHerramientas.add(jMenuItemSIFTDrawMatches);
		jMenuItemSurf.setEnabled(false);
		jMenuHerramientas.add(jMenuItemSurf);
		
		jMenuHerramientas.add(new JSeparator());

		jMenuItemEroding.setText("Eroding");
		jMenuItemEroding.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jMenuItemErodingActionPerformed(evt);
			}
		});
		jMenuHerramientas.add(jMenuItemEroding);

		jMenuItemDilating.setText("Dilating");
		jMenuItemDilating.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jMenuItemDilatingActionPerformed(evt);
			}
		});
		jMenuHerramientas.add(jMenuItemDilating);

		jMenuItemOpen.setText("Opening");
		jMenuItemOpen.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jMenuItemOpenActionPerformed(evt);
			}
		});
		jMenuHerramientas.add(jMenuItemOpen);

		jMenuItemClose.setText("Closing");
		jMenuItemClose.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jMenuItemCloseActionPerformed(evt);
			}
		});
		jMenuHerramientas.add(jMenuItemClose);

		jMenuHerramientas.add(new JSeparator());

		jMenuItemCany.setText("Cany");
		jMenuItemCany.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jMenuItemCanyActionPerformed(evt);
			}
		});
		jMenuHerramientas.add(jMenuItemCany);
		
		jMenuItemHu.setText("Hu Moments");
		jMenuItemHu.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jMenuItemHuActionPerformed(evt);
			}
		});
		jMenuHerramientas.add(jMenuItemHu);
		
		jMenuItemSaveDescriptors.setText("Save Descriptors");
		jMenuItemSaveDescriptors.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jMenuItemSaveDescriptorsActionPerformed(evt);
			}
		});
		jMenuHerramientas.add(jMenuItemSaveDescriptors);

		jMenuItemHoughThreshold.setText("Hough Lines Transform");
		jMenuItemHoughThreshold.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jMenuItemHoughThresholdActionPerformed(evt);
			}
		});
		jMenuHerramientas.add(jMenuItemHoughThreshold);
		
		jMenuHerramientas.add(new JSeparator());
		
		jMenuItemCascade.setText("Cascade classifier");
		jMenuItemCascade.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jMenuItemCascadeActionPerformed(evt);
			}
		});
		jMenuHerramientas.add(jMenuItemCascade);
		
		jMenuHerramientas.add(new JSeparator());
		
		jMenuItemBackgroundSubtraction.setText("Background subtraction (webcam)");
		jMenuItemBackgroundSubtraction.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jMenuItemBackgroundSubtractionActionPerformed(evt);
			}
		});
		jMenuHerramientas.add(jMenuItemBackgroundSubtraction);

		jMenuBar.add(jMenuHerramientas);
		
		jCentroide.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jCentroideActionPerformed(evt);
			}
		});
		jMenuHerramientas.add(jCentroide);
		jCentroide.setText("Clustering - Centroids (webcam)");
		
		jFinalTracking = new JMenuItem();
		jFinalTracking.addActionListener(new ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jFinalTrackingActionPerformed(evt);
			}
		});
		jMenuHerramientas.add(jFinalTracking);
		jFinalTracking.setText("Final tracking (webcam)");
		

		jMenuFiltros.setText("Filters");

		jMenuItemGaussian.setText("Gaussian");
		jMenuItemGaussian.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jMenuItemGaussianActionPerformed(evt);
			}
		});
		jMenuFiltros.add(jMenuItemGaussian);

		jMenuBar.add(jMenuFiltros);

		jMenuConvolucion.setText("Convolution");

		jMenuItemNucleo.setText("Kernel NxN");
		jMenuItemNucleo.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jMenuItemNucleoActionPerformed(evt);
			}
		});
		jMenuConvolucion.add(jMenuItemNucleo);

		jMenuItemBordes.setText("Sobel + Prewitt");
		jMenuItemBordes.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jMenuItemBordesActionPerformed(evt);
			}
		});
		jMenuConvolucion.add(jMenuItemBordes);

		jMenuBar.add(jMenuConvolucion);

		jMenuAyuda.setText("Help");

		jMenuItemLotes.setText("Batch!");
		jMenuItemLotes.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				//porLotes();
			}
		});
		jMenuAyuda.add(jMenuItemLotes);

		jMenuBar.add(jMenuAyuda);

		setJMenuBar(jMenuBar);

		pack();
		setLocationRelativeTo(null);
	}

	// ARCHIVO

	/**
	 * Abrir imagen
	 * 
	 * @param evt
	 */
	private void jMenuItemAbrirImagenActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_jMenuItem1ActionPerformed
		jMenuItemUsarMod.setEnabled(true);

		jMenuItemAjustar.setEnabled(true);

		jMenuItemAGris.setEnabled(true);
		jMenuItemAHSV.setEnabled(true);
		jMenuItemEqualizer.setEnabled(true);
		jMenuItemBackProjection.setEnabled(true);
		jMenuItemThreshold.setEnabled(true);
		jMenuItemWaterShed.setEnabled(true);
		jMenuItemFindContours.setEnabled(true);
		jMenuItemSift.setEnabled(true);
		jMenuItemSurf.setEnabled(true);
		jMenuItemDilating.setEnabled(true);
		jMenuItemEroding.setEnabled(true);
		jMenuItemOpen.setEnabled(true);
		jMenuItemClose.setEnabled(true);
		jMenuItemCany.setEnabled(true);
		jMenuItemHoughThreshold.setEnabled(true);
		jMenuItemHu.setEnabled(true);
		jMenuItemCascade.setEnabled(true);

		jMenuItemGaussian.setEnabled(true);

		jMenuItemNucleo.setEnabled(true);
		jMenuItemBordes.setEnabled(true);
		
		jLabelMod.setText("");
		
		JFileChooser fileChooser = new JFileChooser();
		FileFilter types = new FileNameExtensionFilter("Imagenes (jpg, png)", "jpg", "png");
		fileChooser.addChoosableFileFilter(types);
		fileChooser.setFileFilter(types);
		int returnValue = fileChooser.showOpenDialog(this);
		if (returnValue == JFileChooser.APPROVE_OPTION) {
			File selectedFile = fileChooser.getSelectedFile();
			filename = selectedFile.getName();
			image = CoreModule.readMatFromImageFile(selectedFile.getAbsolutePath());
			bydefault = CoreModule.readMatFromImageFile(rutaNoData);
			resizeImage = new Mat();
			resizeImageByDefault = new Mat();
			CoreModule.resizeMat(bydefault, resizeImageByDefault, size);
			CoreModule.resizeMat(image, resizeImage, size);
			jLabelOriginal.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImage, ".png")));
			jLabelMod.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImageByDefault, ".png")));
		}

		jLabelEstado.setText("Imagen abierta");
	}

	/**
	 * Abrir segunda imagen
	 * 
	 * @param evt
	 * 
	 */
	private void jMenuItemAbrirSegundaImagenActionPerformed(java.awt.event.ActionEvent evt) {
		jMenuItemUsarMod.setEnabled(true);

		jMenuItemAjustar.setEnabled(true);

		jMenuItemSIFTDrawMatches.setEnabled(true);

		JFileChooser fileChooser = new JFileChooser();
		FileFilter types = new FileNameExtensionFilter("Imagenes (jpg, png)", "jpg", "png");
		fileChooser.addChoosableFileFilter(types);
		fileChooser.setFileFilter(types);
		int returnValue = fileChooser.showOpenDialog(this);
		if (returnValue == JFileChooser.APPROVE_OPTION) {
			File selectedFile = fileChooser.getSelectedFile();
			//image = CoreModule.readMatFromImageFile(selectedFile.getAbsolutePath());						
			imageMod = CoreModule.readMatFromImageFile(selectedFile.getAbsolutePath());
			//resizeImage = new Mat();
			resizeImageMod = new Mat();
			CoreModule.resizeMat(imageMod, resizeImageMod, size);
			//CoreModule.resizeMat(image, resizeImage, size);
			//jLabelOriginal.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImage, ".png")));
			jLabelMod.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImageMod, ".png")));
		}
		jLabelEstado.setText("Segunda imagen abierta");
	}
	
	/**
	 * Guardar imagen resultante
	 * 
	 * @param evt
	 */
	private void jMenuItemGuardarImagenActionPerformed(java.awt.event.ActionEvent evt) {
		if (resizeImageMod != null) {
			System.out.println("Guardando image...");
			JFileChooser fileChooser = new JFileChooser();
			FileFilter types = new FileNameExtensionFilter("Image files (jpg, png)", "jpg", "png");
			fileChooser.addChoosableFileFilter(types);
			fileChooser.setFileFilter(types);
			fileChooser.setDialogTitle("Specify a file to save");
			int userSelection = fileChooser.showSaveDialog(this);
			if (userSelection == JFileChooser.APPROVE_OPTION) {
				File fileToSave = fileChooser.getSelectedFile();
				System.out.println("Save as file: " + fileToSave.getAbsolutePath());
				CoreModule.writeMatToFile(resizeImageMod, fileToSave.getAbsolutePath());
			}
		}
		jLabelEstado.setText("Imagen guardada");
	}

	/**
	 * Usar imagen modificada
	 * 
	 * @param evt
	 */
	private void jMenuItemUsarModActionPerformed(java.awt.event.ActionEvent evt) {
		image = imageMod;
		imageMod = null;

		CoreModule.resizeMat(bydefault, resizeImageByDefault, size);
		CoreModule.resizeMat(image, resizeImage, size);
		jLabelOriginal.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImage, ".png")));
		jLabelMod.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImageByDefault, ".png")));

		jLabelEstado.setText("Imagen modificada como principal");
	}

	/**
	 * Cerrar aplicacion
	 * 
	 * @param evt
	 */
	private void jMenuItemSalirActionPerformed(java.awt.event.ActionEvent evt) {
		System.exit(0);
	}

	// EDICION

	/**
	 * Limpiar imagenes
	 * 
	 * @param evt
	 */
	private void jMenuItemLimpiarActionPerformed(java.awt.event.ActionEvent evt) {
		initModel();
	}

	/**
	 * Ajustar imagenes a la ventana
	 * 
	 * @param evt
	 */
	private void jMenuItemAjustarActionPerformed(java.awt.event.ActionEvent evt) {
		ajustarPanel();
	}

	// HERRAMIENTAS

	/**
	 * Convertir imagen a gris
	 * 
	 * @param evt
	 */
	private void jMenuItemAGrisActionPerformed(java.awt.event.ActionEvent evt) {
		if (image != null) {
			jMenuItemGuardarImagen.setEnabled(true);
			imageMod = new Mat();
			CoreModule.matToGraColor(image, imageMod);
			resizeImageMod = new Mat();
			CoreModule.resizeMat(imageMod, resizeImageMod, size);
			jLabelMod.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImageMod, ".png")));
		}
		jLabelEstado.setText("Imagen a gris");
	}

	/**
	 * Convertir imagen a HSV
	 * 
	 * @param evt
	 */
	private void jMenuItemAHSVActionPerformed(java.awt.event.ActionEvent evt) {
		if (image != null) {
			jMenuItemGuardarImagen.setEnabled(true);
			imageMod = new Mat();
			try {
				CoreModule.matToHSVColor(image, imageMod);
			} catch (Exception e) {
				jLabelEstado.setText(e.getMessage());
				return;
			}
			resizeImageMod = new Mat();
			CoreModule.resizeMat(imageMod, resizeImageMod, size);
			jLabelMod.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImageMod, ".png")));
		}
		jLabelEstado.setText("Imagen a HSV");
	}

	/**
	 * Equalizar imagen, la pasa a escala de grises y la equaliza con la funcion
	 * 
	 * @param evt
	 */
	private void jMenuItemEqualizerActionPerformed(java.awt.event.ActionEvent evt) {
		if (image != null) {
			jMenuItemGuardarImagen.setEnabled(true);
			imageMod = new Mat();
			CoreModule.matToGraColor(image, imageMod);
			CoreModule.equilizer(imageMod, imageMod);
			resizeImageMod = new Mat();
			CoreModule.resizeMat(imageMod, resizeImageMod, size);
			jLabelMod.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImageMod, ".png")));
		}
		jLabelEstado.setText("Imagen equalizada");
	}

	/**
	 * Elimiar fondo imagen con background projection
	 * 
	 * @param evt
	 */
	private void jMenuItemBackProjectionActionPerformed(java.awt.event.ActionEvent evt) {
		if (image != null) {
			jMenuItemGuardarImagen.setEnabled(true);
			imageMod = new Mat();
			CoreModule.backProjection(image, imageMod);
			resizeImageMod = new Mat();
			CoreModule.resizeMat(imageMod, resizeImageMod, size);
			jLabelMod.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImageMod, ".png")));
		}
		jLabelEstado.setText("Imagen back projection");
	}

	/**
	 * Threshold
	 * 
	 * @param evt
	 */
	private void jMenuItemThresholdActionPerformed(ActionEvent evt) {
		if (image != null) {
			String resp = (String) JOptionPane.showInputDialog(this, "Introduza tipo(0,1,2,3,4),valor(0-255)", "Threshold",
					JOptionPane.QUESTION_MESSAGE, null, null, "3,0");
			if (resp != null) {
				int threshold_type = 3;
				int threshold_value = 0;
				int max_value = 255;
				int max_type = 4;
				int max_BINARY_value = 255;

				StringTokenizer st = new StringTokenizer(resp, ",");
				threshold_type = Integer.parseInt((String) st.nextElement());
				threshold_value = Integer.parseInt((String) st.nextElement());
				if (threshold_type >= 0 && threshold_type <= max_type && threshold_value >= 0 && threshold_value <= max_value) {
					jMenuItemGuardarImagen.setEnabled(true);
					imageMod = new Mat();
					CoreModule.threshold(image, threshold_value, max_BINARY_value, threshold_type, imageMod);
					resizeImageMod = new Mat();
					CoreModule.resizeMat(imageMod, resizeImageMod, size);
					jLabelMod.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImageMod, ".png")));
					jLabelEstado.setText("Imagen con Threshold aplicado");
				} else {
					jLabelEstado.setText("Error tipo o valor threshold no valido");
				}
			}
		}
	}

	/**
	 * Whatershed
	 * 
	 * @param evt
	 */
	private void jMenuItemWhatershedActionPerformed(ActionEvent evt) {
		if (image != null) {
			String resp = (String) JOptionPane.showInputDialog(this, "Introduza watershedSegmentation(0) o watershed(1)",
					"Whatershed", JOptionPane.QUESTION_MESSAGE, null, null, "1");
			if (resp != null) {
				boolean watershed = true;
				if (resp.compareTo("0") == 0)
					watershed = false;
				else if (resp.compareTo("1") == 0)
					watershed = true;
				else
					jLabelEstado.setText("Error tipo watershed no valido");
				if (jLabelEstado.getText().compareTo("Error tipo watershed no valido") != 0) {
					jMenuItemGuardarImagen.setEnabled(true);
					imageMod = CoreModule.watershed(image, watershed);
					resizeImageMod = new Mat();
					CoreModule.resizeMat(imageMod, resizeImageMod, size);
					jLabelMod.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImageMod, ".png")));

					if (watershed)
						jLabelEstado.setText("Imagen con watershed aplicado");
					else
						jLabelEstado.setText("Imagen con watershedSegmentation aplicado");
				}
			}
		}
	}
	
	/**
	 * FindContours
	 * 
	 * @param evt
	 */
	private void jMenuItemFindContoursActionPerformed(ActionEvent evt) {
		if (image != null) {
			jMenuItemGuardarImagen.setEnabled(true);
			imageMod = CoreModule.findContours(image);
			resizeImageMod = new Mat();
			CoreModule.resizeMat(imageMod, resizeImageMod, size);
			jLabelMod.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImageMod, ".png")));
			jLabelEstado.setText("Imagen con Find Contours aplicado");
		}
	}
	
	/**
	 * Sift
	 * 
	 * @param evt
	 */
	private void jMenuItemSiftActionPerformed(ActionEvent evt) {
		if (image != null) {
				jMenuItemGuardarImagen.setEnabled(true);
				imageMod = CoreModule.sift(image);
				resizeImageMod = new Mat();
				CoreModule.resizeMat(imageMod, resizeImageMod, size);
				jLabelMod.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImageMod, ".png")));
				jLabelEstado.setText("Imagen con Sift aplicado");
		}
	}
	
	/**
	 * SIFT Draw Matches
	 * 
	 * @param evt
	 */
	private void jMenuItemSIFTDrawMatchestActionPerformed(ActionEvent evt) {
		System.out.println("Aplicandoooooo SIFT Draw Matches");
		if (image != null && imageMod != null) {
				jLabelEstado.setText("Aplicado SIFT Draw Matches");
				//jMenuItemGuardarImagen.setEnabled(true);
				//imagesiftMod = CoreModule.sift(image);
				//resizeImageMod = new Mat();
				//CoreModule.resizeMat(imageMod, resizeImageMod, size);
				//jLabelMod.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImageMod, ".png")));
				jLabelEstado.setText("Aplicando SIFT Draw Matches");
				JFrame ventanaSIFTDrawMatches = new JFrame("SIFT Draw Matches");
				ventanaSIFTDrawMatches.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
				ventanaSIFTDrawMatches.setLocationRelativeTo(null);
				JPanel panelSIFTDrawMatches = new JPanel();
				panelSIFTDrawMatches.setLayout(new java.awt.BorderLayout());
				JLabel labelSIFTDrawMatches = new JLabel();
				panelSIFTDrawMatches.add(labelSIFTDrawMatches, java.awt.BorderLayout.CENTER);
				ventanaSIFTDrawMatches.getContentPane().add(panelSIFTDrawMatches, java.awt.BorderLayout.CENTER);
				//ventanaSIFTDrawMatches.pack();
				ventanaSIFTDrawMatches.setResizable(false);

				Mat sift_matches = new Mat();
				CoreModule.sift(image, imageMod, sift_matches);
				ventanaSIFTDrawMatches.setSize(sift_matches.width(), sift_matches.height()+28);
				labelSIFTDrawMatches.setIcon(new ImageIcon(CoreModule.matToBufferedImage(sift_matches, ".png")));
				
				ventanaSIFTDrawMatches.setVisible(true);
		}
	}
	
	
	/**
	 * Surf
	 * 
	 * @param evt
	 */
	private void jMenuItemSurfActionPerformed(ActionEvent evt) {
		if (image != null) {
			if (image != null) {
				jMenuItemGuardarImagen.setEnabled(true);
				imageMod = CoreModule.surf(image);
				resizeImageMod = new Mat();
				CoreModule.resizeMat(imageMod, resizeImageMod, size);
				jLabelMod.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImageMod, ".png")));
				jLabelEstado.setText("Image after applying SURF");
			}
		}
	}
	
	/**
	 * Eroding
	 * 
	 * @param evt
	 */
	private void jMenuItemErodingActionPerformed(java.awt.event.ActionEvent evt) {
		if (image != null) {
			String nucleo = (String) JOptionPane.showInputDialog(this, "Introduza tipo(0,1,2),tamañoMatriz", "Eroding",
					JOptionPane.QUESTION_MESSAGE, null, null, "0,3");

			if (nucleo != null) {
				int element = 0;
				int kernelSize = 3;

				StringTokenizer st = new StringTokenizer(nucleo, ",");
				element = Integer.parseInt((String) st.nextElement());
				kernelSize = Integer.parseInt((String) st.nextElement());

				jMenuItemGuardarImagen.setEnabled(true);
				imageMod = new Mat();
				CoreModule.eroding(image, element, kernelSize, imageMod);
				resizeImageMod = new Mat();
				CoreModule.resizeMat(imageMod, resizeImageMod, size);
				jLabelMod.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImageMod, ".png")));

				jLabelEstado.setText("Imagen erosionada");
			}
		}
	}

	/**
	 * Dilating
	 * 
	 * @param evt
	 */
	private void jMenuItemDilatingActionPerformed(java.awt.event.ActionEvent evt) {
		if (image != null) {
			String nucleo = (String) JOptionPane.showInputDialog(this, "Introduza tipo(0,1,2),tamañoMatriz", "Eroding",
					JOptionPane.QUESTION_MESSAGE, null, null, "0,3");

			if (nucleo != null) {
				int element = 0;
				int kernelSize = 3;

				StringTokenizer st = new StringTokenizer(nucleo, ",");
				element = Integer.parseInt((String) st.nextElement());
				kernelSize = Integer.parseInt((String) st.nextElement());

				jMenuItemGuardarImagen.setEnabled(true);
				imageMod = new Mat();
				CoreModule.dilating(image, element, kernelSize, imageMod);
				resizeImageMod = new Mat();
				CoreModule.resizeMat(imageMod, resizeImageMod, size);
				jLabelMod.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImageMod, ".png")));

				jLabelEstado.setText("Imagen dilatada");
			}
		}
	}

	/**
	 * Open
	 * 
	 * @param evt
	 */
	private void jMenuItemOpenActionPerformed(java.awt.event.ActionEvent evt) {
		if (image != null) {
			String nucleo = (String) JOptionPane.showInputDialog(this, "Introduza tipo(0,1,2),tamañoMatriz", "Eroding",
					JOptionPane.QUESTION_MESSAGE, null, null, "0,3");

			if (nucleo != null) {
				int element = 0;
				int kernelSize = 3;

				StringTokenizer st = new StringTokenizer(nucleo, ",");
				element = Integer.parseInt((String) st.nextElement());
				kernelSize = Integer.parseInt((String) st.nextElement());

				jMenuItemGuardarImagen.setEnabled(true);
				imageMod = new Mat();
				CoreModule.opening(image, element, kernelSize, imageMod);
				resizeImageMod = new Mat();
				CoreModule.resizeMat(imageMod, resizeImageMod, size);
				jLabelMod.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImageMod, ".png")));

				jLabelEstado.setText("Imagen erosionada");
			}
		}
	}

	/**
	 * Close
	 * 
	 * @param evt
	 */
	private void jMenuItemCloseActionPerformed(java.awt.event.ActionEvent evt) {
		if (image != null) {
			String nucleo = (String) JOptionPane.showInputDialog(this, "Introduza tipo(0,1,2),tamañoMatriz", "Eroding",
					JOptionPane.QUESTION_MESSAGE, null, null, "0,3");

			if (nucleo != null) {
				int element = 0;
				int kernelSize = 3;

				StringTokenizer st = new StringTokenizer(nucleo, ",");
				element = Integer.parseInt((String) st.nextElement());
				kernelSize = Integer.parseInt((String) st.nextElement());

				jMenuItemGuardarImagen.setEnabled(true);
				imageMod = new Mat();
				CoreModule.closing(image, element, kernelSize, imageMod);
				resizeImageMod = new Mat();
				CoreModule.resizeMat(imageMod, resizeImageMod, size);
				jLabelMod.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImageMod, ".png")));

				jLabelEstado.setText("Imagen dilatada");
			}
		}
	}

	/**
	 * Cany
	 * 
	 * @param evt
	 */
	private void jMenuItemCanyActionPerformed(java.awt.event.ActionEvent evt) {
		if (image != null) {
			jMenuItemGuardarImagen.setEnabled(true);
			imageMod = new Mat();
			CoreModule.matToCany(image, imageMod);
			resizeImageMod = new Mat();
			CoreModule.resizeMat(imageMod, resizeImageMod, size);
			jLabelMod.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImageMod, ".png")));
		}
		jLabelEstado.setText("Aplicar Cany");
	}

	// DETECTAR LÍNEAS

	/**
	 * Aplicar un filtro personaliza a la imagen
	 * 
	 * @param evt
	 */
	private void jMenuItemHoughThresholdActionPerformed(java.awt.event.ActionEvent evt) {
		if (image != null) {
			int threshold = Integer.parseInt((String) JOptionPane.showInputDialog(this, "Introduza número de intersecciones",
					"Threshold", JOptionPane.QUESTION_MESSAGE, null, null, 100));
			// int threshold = 100;
			if (threshold > 0) {
				// Procesar imagen
				jMenuItemGuardarImagen.setEnabled(true);
				imageMod = new Mat();
				
				Mat lines = new Mat();
				Mat imageRGB = new Mat();
				
				
				try{
					CoreModule.matToGraColor(image,imageMod);
					CoreModule.matToCany(image, imageMod);
				}catch(Exception e){
					imageMod=image;
				}

				
				Imgproc.HoughLinesP(imageMod, lines, 1, Math.PI / 180, threshold);

				try{
					CoreModule.matToColor(image,imageRGB);
				}catch(Exception e){
					imageRGB=image;
				}
				
				Scalar red = new Scalar(0, 0, 255);

				for (int x = 0; x < lines.cols(); x++) {
					double[] vec = lines.get(0, x);

					if (vec == null)
						break;

					double x1 = vec[0], y1 = vec[1], x2 = vec[2], y2 = vec[3];
					Point start = new Point(x1, y1);
					Point end = new Point(x2, y2);

					Core.line(imageRGB, start, end, red, 5);
				}

				resizeImageMod = new Mat();
				CoreModule.resizeMat(imageRGB, resizeImageMod, size);
				jLabelMod.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImageMod, ".png")));

				jLabelEstado.setText("Hough Line Transform");
			}
		}
	}
	
	/**
	 * Hu Moments
	 * 
	 * @param evt
	 */
	private void jMenuItemHuActionPerformed(java.awt.event.ActionEvent evt) {
		if (image != null) {
			jMenuItemGuardarImagen.setEnabled(true);
			imageMod = new Mat();	
			CoreModule.matToGraColor(image, image);
			CoreModule.huMoments(image, imageMod);
			resizeImageMod = new Mat();
			CoreModule.resizeMat(image, resizeImageMod, size);
			jLabelMod.setIcon(null);
			jLabelMod.setText("<html> Hu[1] = "+imageMod.get(0,0)[0]+"<br>"+"Hu[2] = "+imageMod.get(1,0)[0]+"<br>"+"Hu[3] = "+imageMod.get(2,0)[0]+"<br>"+"Hu[4] = "+imageMod.get(3,0)[0]+"<br>"+"Hu[5] = "+imageMod.get(4,0)[0]+"<br>"+"Hu[6] = "+imageMod.get(5,0)[0]+"<br>"+"Hu[7] = "+imageMod.get(6,0)[0]+"</html>");
		}
		jLabelEstado.setText("Hu[1] = "+imageMod.get(0,0)[0]+"Hu[2] = "+imageMod.get(1,0)[0]+"Hu[3] = "+imageMod.get(2,0)[0]+"Hu[4] = "+imageMod.get(3,0)[0]+"Hu[5] = "+imageMod.get(4,0)[0]+"Hu[6] = "+imageMod.get(5,0)[0]+"Hu[7] = "+imageMod.get(6,0)[0]);
	}


	/**
	 * Save Descriptors
	 * 
	 * @param evt
	 */
	private void jMenuItemSaveDescriptorsActionPerformed(java.awt.event.ActionEvent evt) {
		if (image != null) {
			jMenuItemGuardarImagen.setEnabled(true);
			imageMod = new Mat();
			CoreModule.matToGraColor(image, image);
			
			//Get area
			double area = CoreModule.getArea(image);
			
			//Get perimeter
			double perimeter=CoreModule.getPerimeter(image);
			
			//Get Density
			double density=area/Math.pow(perimeter, 2);
								
			CoreModule.huMoments(image, imageMod);
			
			/*
			//Get mayor/minor
			RotatedRect axes = new RotatedRect();
			axes = CoreModule.getAxes(image);
			double axesdiv=Math.max(axes.size.width, axes.size.height)/Math.min(axes.size.width, axes.size.height);
			*/
			
			String clase = (String) JOptionPane.showInputDialog(this, "Enter class name: ", "Descriptors",
					JOptionPane.QUESTION_MESSAGE, null, null, "none");
			
			String ruta = "descriptors.csv";
			File archivo = new File(ruta);
			BufferedWriter bw = null;
			if(archivo.exists()) {
				try {
					bw = new BufferedWriter(new FileWriter(archivo,true));
					bw.newLine();
		            bw.write(filename+","+area+","+perimeter+","+density+","+imageMod.get(0,0)[0]+","+imageMod.get(1,0)[0]+","+imageMod.get(2,0)[0]+","+imageMod.get(3,0)[0]+","+imageMod.get(4,0)[0]+","+imageMod.get(5,0)[0]+","+imageMod.get(6,0)[0]+","+clase);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			} else {
				try {
					bw = new BufferedWriter(new FileWriter(archivo));
		            bw.write("filename,area,perimeter,density,hu1,hu2,hu3,hu4,hu5,hu6,hu7,class");
		            bw.newLine();
		            bw.write(filename+","+area+","+perimeter+","+density+","+imageMod.get(0,0)[0]+","+imageMod.get(1,0)[0]+","+imageMod.get(2,0)[0]+","+imageMod.get(3,0)[0]+","+imageMod.get(4,0)[0]+","+imageMod.get(5,0)[0]+","+imageMod.get(6,0)[0]+","+clase);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			try {
				bw.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		jLabelEstado.setText("Hu[1] = "+imageMod.get(0,0)[0]+"Hu[2] = "+imageMod.get(1,0)[0]+"Hu[3] = "+imageMod.get(2,0)[0]+"Hu[4] = "+imageMod.get(3,0)[0]+"Hu[5] = "+imageMod.get(4,0)[0]+"Hu[6] = "+imageMod.get(5,0)[0]+"Hu[7] = "+imageMod.get(6,0)[0]);
	}
	
	/**
	 * Cascade classifier
	 * 
	 * @param evt
	 */
	private void jMenuItemCascadeActionPerformed(ActionEvent evt) {
		if (image != null) {
				// Abrir elementos de xml
				JFileChooser fileChooser = new JFileChooser();
				FileFilter types = new FileNameExtensionFilter("Cascade classifier XML (xml)", "xml");
				fileChooser.addChoosableFileFilter(types);
				fileChooser.setFileFilter(types);
				fileChooser.setCurrentDirectory(new File(workingDirectory + File.separator + "xml"));
				int returnValue = fileChooser.showOpenDialog(this);
				if (returnValue == JFileChooser.APPROVE_OPTION) {
					File selectedFile = fileChooser.getSelectedFile();
					jMenuItemGuardarImagen.setEnabled(true);
					imageMod = new Mat();
					int num;
					try {
						num = CoreModule.cascade(image, selectedFile.getAbsolutePath(), imageMod);
						jLabelEstado.setText("Detectados " + num + " objetos en la imagen");
						
						if(num != 0){
							resizeImageMod = new Mat();
							CoreModule.resizeMat(imageMod, resizeImageMod, size);
							jLabelMod.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImageMod, ".png")));
						}else{
							resizeImageMod = new Mat();
							CoreModule.resizeMat(image, resizeImageMod, size);
							jLabelMod.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImageMod, ".png")));
						}
					} catch (Exception e) {
						jLabelEstado.setText("Error en deteccion de objetos");
					}
				}
		}
	}
	
	/**
	 * Background substraction
	 * 
	 * @param evt
	 */
	private void jMenuItemBackgroundSubtractionActionPerformed(ActionEvent evt) {
		new Thread(new BackgroundSubtraction()).start();
	}
	
	/**
	 * Centroide
	 * 
	 * @param evt
	 */
	private void jCentroideActionPerformed(ActionEvent evt) {
		new Thread(new CentroideSURF_DistanciaMejoradoClustering()).start();
		
	}
	/**
	 * Final tracking
	 * 
	 * @param evt
	 */
	private void jFinalTrackingActionPerformed(ActionEvent evt) {
		new Thread(new BackgroundSubtraction_ClusteringCentroide()).start();
		
	}
	
	// FILTROS

	/**
	 * Filtro gaussiano
	 * 
	 * @param evt
	 */
	private void jMenuItemGaussianActionPerformed(java.awt.event.ActionEvent evt) {
		if (image != null) {
			jMenuItemGuardarImagen.setEnabled(true);
			imageMod = new Mat();
			CoreModule.gaussian(image, imageMod);
			resizeImageMod = new Mat();
			CoreModule.resizeMat(imageMod, resizeImageMod, size);
			jLabelMod.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImageMod, ".png")));
		}
		jLabelEstado.setText("Imagen con filtro Gaussiano");
	}

	// CONVOLUCION

	/**
	 * Aplicar un filtro personaliza a la imagen
	 * 
	 * @param evt
	 */
	private void jMenuItemNucleoActionPerformed(java.awt.event.ActionEvent evt) {
		if (image != null) {
			String nucleo = (String) JOptionPane.showInputDialog(this, "Introduza nucleo NxN", "Nucleo 3x3",
					JOptionPane.QUESTION_MESSAGE, null, null, "3:-1,-1,-1;-1,8,-1;-1,-1,-1");

			if (nucleo != null) {
				// Procesar nucleo y hacer matriz
				int kernelSize = 3;
				StringTokenizer st = new StringTokenizer(nucleo, ":");
				kernelSize = Integer.parseInt((String) st.nextElement());
				Mat kernel = new Mat(kernelSize, kernelSize, CvType.CV_32F);
				// Separo en filas
				StringTokenizer stFil = new StringTokenizer((String) st.nextElement(), ";");
				int fila = 0;
				while (stFil.hasMoreElements()) {
					// Separo en columnas
					StringTokenizer stCol = new StringTokenizer((String) stFil.nextElement(), ",");
					int columna = 0;
					while (stCol.hasMoreElements()) {
						kernel.put(fila, columna, Double.parseDouble((String) stCol.nextElement()));
						columna++;
					}
					fila++;
				}

				// Procesar imagen
				jMenuItemGuardarImagen.setEnabled(true);
				imageMod = new Mat();
				CoreModule.convolucion(image, kernel, imageMod);
				resizeImageMod = new Mat();
				CoreModule.resizeMat(imageMod, resizeImageMod, size);
				jLabelMod.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImageMod, ".png")));

				jLabelEstado.setText("Imagen convolucionada");
			}
		}
	}
	
	/**
	 * Detectar bordes
	 * 
	 * @param evt
	 */
	private void jMenuItemBordesActionPerformed(java.awt.event.ActionEvent evt) {
		if (image != null) {
			jMenuItemGuardarImagen.setEnabled(true);
			imageMod = new Mat();
			try {
				CoreModule.bordesConv(image, imageMod);
			} catch (Exception e) {
				jLabelEstado.setText(e.getMessage());
				return;
			}
			resizeImageMod = new Mat();
			CoreModule.resizeMat(imageMod, resizeImageMod, size);
			jLabelMod.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImageMod, ".png")));
		}
		jLabelEstado.setText("Deteccion de bordes en imagen");
	}

	// AYUDA

	/**
	 * Aplicar todas las operaciones a las imagenes de un directorio
	 */
	/*
	private void porLotes() {
		// Abro todas las imagenes de una carpeta
		try {
			String rutaDir = "C:\\Users\\Jose Manuel\\Dropbox\\Compartidas\\ComputerVision [Equipo]\\Fotos cartas";

			Files.walk(Paths.get(rutaDir))
					.forEach(
							filePath -> {
								if (Files.isRegularFile(filePath)) {
									System.out.println(filePath);
									String rutaGua = "C:\\Users\\Jose Manuel\\Dropbox\\Compartidas\\ComputerVision [Equipo]\\Grupo\\Jose\\Imagenes prueba";
									// Procesar imagen
									Mat imagen = new Mat();
									try {
										imagen = CoreModule.readMatFromImageFile(filePath.toString());

										Mat imagenMod = new Mat();
										for (int op = 0; op <= 4; op++) {
											switch (op) {
											case 0:
												CoreModule.matToGraColor(imagen, imagenMod);
												CoreModule.equilizer(imagenMod, imagenMod);
												rutaGua = "C:\\Users\\Jose Manuel\\Dropbox\\Compartidas\\ComputerVision [Equipo]\\Grupo\\Jose\\Imagenes prueba\\Equalizer";
												break;
											case 1:
												CoreModule.backProjection(imagen, imagenMod);
												rutaGua = "C:\\Users\\Jose Manuel\\Dropbox\\Compartidas\\ComputerVision [Equipo]\\Grupo\\Jose\\Imagenes prueba\\BackProjection";
												break;
											case 2:
												Mat nucleo = new Mat(3, 3, CvType.CV_32F);
												nucleo.put(0, 0, -1);
												nucleo.put(0, 1, -1);
												nucleo.put(0, 2, -1);
												nucleo.put(1, 0, -1);
												nucleo.put(1, 1, 8);
												nucleo.put(1, 2, -1);
												nucleo.put(2, 0, -1);
												nucleo.put(2, 1, -1);
												nucleo.put(2, 2, -1);

												CoreModule.convolucion(imagen, nucleo, imagenMod);
												rutaGua = "C:\\Users\\Jose Manuel\\Dropbox\\Compartidas\\ComputerVision [Equipo]\\Grupo\\Jose\\Imagenes prueba\\Convolution";
												break;
											case 3:
												CoreModule.eroding(imagen, 0, 2, imagenMod);
												rutaGua = "C:\\Users\\Jose Manuel\\Dropbox\\Compartidas\\ComputerVision [Equipo]\\Grupo\\Jose\\Imagenes prueba\\Eroding";
												break;
											case 4:
												CoreModule.dilating(imagen, 0, 2, imagenMod);
												rutaGua = "C:\\Users\\Jose Manuel\\Dropbox\\Compartidas\\ComputerVision [Equipo]\\Grupo\\Jose\\Imagenes prueba\\Dilating";
												break;
											default:
												break;
											}

											// Guardo imagen
											CoreModule.writeMatToFile(imagenMod, rutaGua + "\\" + filePath.getFileName());
										}
									} catch (Exception ex) {

									}
								}
							});
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	*/
	// FUNCIONES

	/**
	 * Reiniciar aplicacion
	 */
	private void resetData() {
		jMenuItemGuardarImagen.setEnabled(false);
		jMenuItemUsarMod.setEnabled(false);

		jMenuItemLimpiar.setEnabled(true);
		jMenuItemAjustar.setEnabled(false);

		jMenuItemAGris.setEnabled(false);
		jMenuItemAHSV.setEnabled(false);
		jMenuItemEqualizer.setEnabled(false);
		jMenuItemBackProjection.setEnabled(false);
		jMenuItemThreshold.setEnabled(false);
		jMenuItemWaterShed.setEnabled(false);
		jMenuItemFindContours.setEnabled(false);
		jMenuItemSift.setEnabled(false);
		jMenuItemSIFTDrawMatches.setEnabled(false);
		jMenuItemSurf.setEnabled(false);
		jMenuItemDilating.setEnabled(false);
		jMenuItemEroding.setEnabled(false);
		jMenuItemOpen.setEnabled(false);
		jMenuItemClose.setEnabled(false);
		jMenuItemCany.setEnabled(false);
		jMenuItemHoughThreshold.setEnabled(false);
		jMenuItemHu.setEnabled(false);
		jMenuItemCascade.setEnabled(false);
		
		jMenuItemGaussian.setEnabled(false);

		jMenuItemNucleo.setEnabled(false);
		jMenuItemBordes.setEnabled(false);

		jMenuItemLotes.setEnabled(false);

		bydefault = CoreModule.readMatFromImageFile(rutaNoData);
		resizeImageByDefault = new Mat();
		CoreModule.resizeMat(bydefault, resizeImageByDefault, size);
		jLabelOriginal.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImageByDefault, ".png")));
		jLabelMod.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImageByDefault, ".png")));
		jLabelEstado.setText("-");
	}

	/**
	 * Ajustar imagen a la ventana y refrescar
	 */
	private void ajustarPanel() {
		size = new Size(jPanelOriginal.getWidth(), jPanelOriginal.getHeight());
		if (resizeImage != null && resizeImageMod != null) {
			CoreModule.resizeMat(resizeImage, resizeImage, size);
			CoreModule.resizeMat(resizeImageMod, resizeImageMod, size);
			jLabelOriginal.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImage, ".png")));
			jLabelMod.setIcon(new ImageIcon(CoreModule.matToBufferedImage(resizeImageMod, ".png")));
		}
	}
}
